"use strict";
/**
 * 微信响应工具
 * Created by liamjung on 2018/6/27.
 */
const ejs = require("ejs");
const WXBizMsgCrypt = require("wechat-crypto");

/*!
 * 响应模版
 */
/* eslint-disable indent */
const tpl = ['<xml>',
    '<ToUserName><![CDATA[<%-toUsername%>]]></ToUserName>',
    '<FromUserName><![CDATA[<%-fromUsername%>]]></FromUserName>',
    '<CreateTime><%=createTime%></CreateTime>',
    '<MsgType><![CDATA[<%=msgType%>]]></MsgType>',
    '<% if (msgType === "news") { %>',
    '<ArticleCount><%=content.length%></ArticleCount>',
    '<Articles>',
    '<% content.forEach(function(item){ %>',
    '<item>',
    '<Title><![CDATA[<%-item.title%>]]></Title>',
    '<Description><![CDATA[<%-item.description%>]]></Description>',
    '<PicUrl><![CDATA[<%-item.picUrl || item.picurl || item.pic || item.thumb_url %>]]></PicUrl>',
    '<Url><![CDATA[<%-item.url%>]]></Url>',
    '</item>',
    '<% }); %>',
    '</Articles>',
    '<% } else if (msgType === "music") { %>',
    '<Music>',
    '<Title><![CDATA[<%-content.title%>]]></Title>',
    '<Description><![CDATA[<%-content.description%>]]></Description>',
    '<MusicUrl><![CDATA[<%-content.musicUrl || content.url %>]]></MusicUrl>',
    '<HQMusicUrl><![CDATA[<%-content.hqMusicUrl || content.hqUrl %>]]></HQMusicUrl>',
    '</Music>',
    '<% } else if (msgType === "voice") { %>',
    '<Voice>',
    '<MediaId><![CDATA[<%-content.mediaId%>]]></MediaId>',
    '</Voice>',
    '<% } else if (msgType === "image") { %>',
    '<Image>',
    '<MediaId><![CDATA[<%-content.mediaId%>]]></MediaId>',
    '</Image>',
    '<% } else if (msgType === "video") { %>',
    '<Video>',
    '<MediaId><![CDATA[<%-content.mediaId%>]]></MediaId>',
    '<Title><![CDATA[<%-content.title%>]]></Title>',
    '<Description><![CDATA[<%-content.description%>]]></Description>',
    '</Video>',
    '<% } else if (msgType === "transfer_customer_service") { %>',
    '<% if (content && content.kfAccount) { %>',
    '<TransInfo>',
    '<KfAccount><![CDATA[<%-content.kfAccount%>]]></KfAccount>',
    '</TransInfo>',
    '<% } %>',
    '<% } else { %>',
    '<Content><![CDATA[<%-content%>]]></Content>',
    '<% } %>',
    '</xml>'].join('');
/* eslint-enable indent */

/*!
 * 编译过后的模版
 */
const compiled = ejs.compile(tpl);

const wrapTpl = '<xml>' +
    '<Encrypt><![CDATA[<%-encrypt%>]]></Encrypt>' +
    '<MsgSignature><![CDATA[<%-signature%>]]></MsgSignature>' +
    '<TimeStamp><%-timestamp%></TimeStamp>' +
    '<Nonce><![CDATA[<%-nonce%>]]></Nonce>' +
    '</xml>';

const encryptWrap = ejs.compile(wrapTpl);

/*!
 * 将内容回复给微信的封装方法
 */
function reply(content, fromUsername, toUsername) {
    let info = {};
    let type = 'text';
    info.content = content || '';
    if (Array.isArray(content)) {
        type = 'news';
    } else if (typeof content === 'object') {
        if (content.hasOwnProperty('type')) {
            // if (content.type === 'customerService') {
            //     return reply2CustomerService(fromUsername, toUsername, content.kfAccount);
            // }
            type = content.type;
            info.content = content.content;
        } else {
            type = 'music';
        }
    }
    info.msgType = type;
    info.createTime = new Date().getTime();
    info.toUsername = toUsername;
    info.fromUsername = fromUsername;

    return compiled(info);
}

function getResp(content, wxMsg, encryptType) {

    let resp = {
        status: 200,
        headers: {},
        body: undefined
    };

    /*
     * 假如服务器无法保证在五秒内处理并回复，可以直接回复空串。
     * 微信服务器不会对此作任何处理，并且不会发起重试。
     */
    if (content === "") {
        resp.body = "";

        return resp;
    }

    let replyMessageXml = reply(content, wxMsg.ToUserName, wxMsg.FromUserName);

    if (!encryptType || encryptType === 'raw') {
        resp.body = replyMessageXml;
    } else {
        const CRYPTOR = new WXBizMsgCrypt(this.token, this.encodingAESKey, this.appid);

        let wrap = {};
        wrap.encrypt = CRYPTOR.encrypt(replyMessageXml);
        wrap.nonce = parseInt((Math.random() * 100000000000), 10);
        wrap.timestamp = new Date().getTime();
        wrap.signature = CRYPTOR.getSignature(wrap.timestamp, wrap.nonce, wrap.encrypt);
        resp.body = encryptWrap(wrap);
    }

    resp.headers["content-type"] = "application/xml";

    return resp;
}

module.exports = {
    getResp
};